package seGobangClient.gaming;
import java.util.*;
import javax.vecmath.*;
import seGobangClient.ISceneController;
import seGobangClient.Rule;
import seGobangClient.CoordinateTransfer.*;
import seGobangClient.GlobalController;
/**
 *
 * @author plus
 */
public class ChessBoard {
    static ISceneController MyController;
    HashMap <Point2i,Byte> Chesses;                                     //妫嬬洏
    private ArrayList<Point2i> ChessStep;                                       //钀藉瓙璁板綍
    private int iChesses;
    private Rule currentRule;

    void clearChessBoard(){
        Chesses.clear();
        for(int i=-7;i<=7;i++)
            for(int j=-7;j<=7;j++){
                Chesses.put(new Point2i(i,j),new Byte((byte)0));
                MyController.doEvent("RemoveChess", new Point2i(i,j));
            }
        ChessStep.clear();
        this.iChesses=0;
    }
    
    public ChessBoard(ISceneController Controller,Rule currentRule) {
        MyController=Controller;
        this.Chesses = new HashMap <Point2i,Byte>();
        this.ChessStep = new ArrayList<Point2i>();
        this.currentRule = currentRule;
        //clearChessBoard();
    }
    
   public ChessBoard() {
        this.Chesses = new HashMap <Point2i,Byte>();
        this.ChessStep = new ArrayList<Point2i>();
        clearChessBoard();
    }
  
    public boolean testPosition(Point2i pos){
        if (Chesses.get(pos)==0)
            return true;
        else
            return false;
    }
    
    public int putChess(Point2i pos,byte ChessFlag){
         if (Chesses.get(pos)==0){
             if (ChessFlag==-1) MyController.doEvent("AddBlackChess", pos);
             else MyController.doEvent("AddWhiteChess", pos);
             
             Chesses.remove(pos);
             Chesses.put(pos, ChessFlag);
             iChesses++;
             ChessStep.add(pos);
             
             return scanChessBoard(pos);
         }else{
             System.err.println("Position Not Empty");
             return 1;
         }
    }
     
     public int regret(byte RasierFlag) {
        if (iChesses < 1) {
            return 0;
        }
        Byte lastFlag = Chesses.get(ChessStep.get(iChesses - 1));
        if (lastFlag == RasierFlag) {                                              //鎮旀鍙戣捣鑰呬负涓婁釜涓嬪瓙鐨勪汉
            Chesses.remove(ChessStep.get(iChesses - 1));
            Chesses.put(ChessStep.get(iChesses - 1), (byte)0);
            MyController.doEvent("RemoveChess", ChessStep.get(iChesses - 1));
            ChessStep.remove(iChesses-1);
            iChesses--;
            return 1;
        } else {                                                                  //鎮旀鍙戣捣鑰呬负姝ｈ涓嬪瓙鐨勪汉
            if (iChesses < 2) {
                return 0;
            } else {
                Chesses.remove(ChessStep.get(iChesses - 1));
                Chesses.put(ChessStep.get(iChesses - 1), (byte)0);
                MyController.doEvent("RemoveChess", ChessStep.get(iChesses - 1));
                ChessStep.remove(iChesses-1);
                iChesses--;
                Chesses.remove(ChessStep.get(iChesses - 1));
                Chesses.put(ChessStep.get(iChesses - 1), (byte)0);
                MyController.doEvent("RemoveChess", ChessStep.get(iChesses - 1));
                ChessStep.remove(iChesses-1);
                iChesses--;
                return 2;
            }
        }
    }
     
     public String toString(){
         String res=new String();
         for(int i=-7;i<=7;i++){
            for(int j=-7;j<=7;j++)
                res+=Chesses.get(new Point2i(i,j));
            res+='\n';
         }
         return res;
     }
     
     private int scanChessBoard(Point2i RecentPos){                                             //鎵弿妫嬬洏
        ForbiddenTool FT=new ForbiddenTool(Chesses,RecentPos);  
        //FT.show_chesstable();
        CoTransfer trans=CoTransfer.getInstance();
        int[][] ChessBox=trans.MatToMatrix(Chesses);
        
        if(FT.Isforbid() && GlobalController.getCurrentRule().forbids){
            MyController.doEvent("Forbidden", Chesses);
            return 0;
        }
        
        if(checkWin(ChessBox)){
        
            MyController.doEvent("Win", Chesses);
            return 0;
            
        }else{
        
            if(iChesses==225){
            
                MyController.doEvent("Draw", Chesses);
                return 0;
            }
            return 1;
        }
        
     }
     
    public boolean checkWin(int ChessBox[][]) {

        for (int i = 0; i < 15; i++) {

            for (int j = 0; j < 15; j++) {

                if (ChessBox[i][j] != 0) {

                    if (lineCheck(i, j, ChessBox)) {

                        return true;
                    }
                }
            }
        }

        return false;

    }

    public boolean lineCheck(int x, int y, int ChessBox[][]) {


        int p1 = 0, n1 = 0, p2 = 0, n2 = 0, p3 = 0, n3 = 0, p4 = 0, n4 = 0;

        boolean sequencep1 = true, sequencen1 = true, sequencep2 = true, sequencen2 = true, sequencep3 = true, sequencen3 = true, sequencep4 = true, sequencen4 = true;

        for (int i = 1; i <= 4; i++) {

            if (sequencep1 && x - i >= 0 && ChessBox[x - i][y] == ChessBox[x][y]) {
                p1++;

            } else {
                sequencep1 = false;
            }

            if (sequencen1 && x + i < 15 && ChessBox[x + i][y] == ChessBox[x][y]) {
                n1++;
            } else {
                sequencen1 = false;
            }

            if (sequencep2 && y - i >= 0 && ChessBox[x][y - i] == ChessBox[x][y]) {
                p2++;
            } else {
                sequencep2 = false;
            }

            if (sequencen2 && y + i < 15 && ChessBox[x][y + i] == ChessBox[x][y]) {
                n2++;
            } else {
                sequencen2 = false;
            }

            if (sequencep3 && x - i >= 0 && y - i >= 0 && ChessBox[x - i][y - i] == ChessBox[x][y]) {
                p3++;
            } else {
                sequencep3 = false;
            }

            if (sequencen3 && x + i < 15 && y + i < 15 && ChessBox[x + i][y + i] == ChessBox[x][y]) {
                n3++;
            } else {
                sequencen3 = false;
            }

            if (sequencep4 && x - i >= 0 && y + i < 15 && ChessBox[x - i][y + i] == ChessBox[x][y]) {
                p4++;
            } else {
                sequencep4 = false;
            }

            if (sequencen4 && x + i < 15 && y - i >= 0 && ChessBox[x + i][y - i] == ChessBox[x][y]) {
                n4++;
            } else {
                sequencen4 = false;
            }

        }

        if (p1 + n1 >= 4 || p2 + n2 >= 4 || p3 + n3 >= 4 || p4 + n4 >= 4) {

            return true;
        } else {

            return false;
        }

    }
}
